﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework;
using System.Windows.Resources;
using System.Threading;
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Diagnostics;

namespace Curling
{
    [DataContractAttribute]
    public class SoundManager
    {
        public enum Sounds
        {
            Hit = 0,
            Broom,
            StartMove,
            Move
        };

        private static bool mute;
        [DataMemberAttribute]
        public static bool Mute
        {
            get
            {
                return mute;
            }
            set
            {
                mute = value;
                if (mute)
                {
                    //foreach (SoundEffectInstance sound in HitSound)
                    //{
                    //    if (sound.State == SoundState.Playing)
                    //    {
                    //        sound.Stop();
                    //    }
                    //}

                    if (BroomSound.State == SoundState.Playing)
                    {
                        BroomSound.Stop();
                    }

                    //if (MoveSound.State == SoundState.Playing)
                    //{
                    //    MoveSound.Stop();
                    //}
                }
            }
        }

        //static SoundEffect[] soundEffects;
        //static SoundEffectInstance[] soundEffectsInstances;

        static BackgroundWorker BackgroundCache;

        static SoundEffectInstance[,] HitSound;
        static SoundEffectInstance BroomSound;
        SoundEffectInstance MoveSound;
        static SoundEffect moveSound;

        static Random rnd;

        static int channel = 0;

        //public static void Play(Sounds soundEffect, double Volume)
        //{
        //    if (soundEffects != null && !Mute)
        //    {
        //        FrameworkDispatcher.Update();
                
        //        //soundEffectsInstances[(int)soundEffect].Apply3D(new AudioListener() { Position = new Vector3(0.0f, 0.0f, -250.0f) }, new AudioEmitter() { Position = new Vector3(0.0f, 0.0f, 0.0f) });
        //        soundEffectsInstances[(int)soundEffect].Pitch = -0.0f;
        //        soundEffectsInstances[(int)soundEffect].Play();
                
        //        //soundEffectsInstances[(int)soundEffect].Volume = 0.01f;// (float)Volume;
        //    }
        //}

        public static void PlayStoneHit(double Volume)
        {
            if (HitSound != null && !SoundManager.Mute)
            {
                FrameworkDispatcher.Update();

                int index;

                if (Volume < 0.25)
                    index = 4;
                else if (Volume < 0.45)
                    index = 3;
                else if (Volume < 0.7)
                    index = 2;
                else if (Volume < 0.9)
                    index = 1;
                else index = 0;

                HitSound[channel, index].Pitch = (float)(-1.0 + (Volume + rnd.NextDouble()) * 0.5);
                HitSound[channel, index].Play();

                channel = (channel + 1) % 4;
            }
        }

        public static void PlayBroomSound(double Intensity)
        {
            if (BroomSound != null && !Mute)
            {
                FrameworkDispatcher.Update();

                if (Intensity > 0.0)
                {
                    if (BroomSound.State != SoundState.Playing)
                        BroomSound.Play();

                    BroomSound.Volume = (float)Intensity;
                }
                else
                {
                    BroomSound.Stop();
                }
            }
        }

        public void LoadSounds()
        {
            if (MoveSound == null)
            {
                MoveSound = moveSound.CreateInstance();
            }
        }

        public void PlayMoveSound(double Volume)
        {
            if (MoveSound != null)
            {
                FrameworkDispatcher.Update();

                if (SoundManager.Mute)
                {
                    if (MoveSound.State == SoundState.Playing)
                    {
                        MoveSound.Stop();
                    }
                }
                else
                {
                    if (Volume <= 0.05)
                    {
                        MoveSound.Stop();
                    }
                    else
                    {
                        MoveSound.Pitch = (float)(-1.0 + Volume);
                        if (MoveSound.State != SoundState.Playing)
                        {
                            MoveSound.Play();
                        }
                    }
                }
            }
        }

        public static void CacheSounds()
        {
            BackgroundCache = new BackgroundWorker();
            BackgroundCache.DoWork += new DoWorkEventHandler(BackgroundCache_DoWork);
            BackgroundCache.RunWorkerAsync();
        }
        
        static void BackgroundCache_DoWork(object sender, DoWorkEventArgs e)
        {
            SoundEffect.MasterVolume = 0.0f;

            //PlayStoneHit(1.0);
            //PlayBroomSound(1.0f);
            ////PlayStartMoveSound();
            //PlayMoveSound(1.0);

            //Thread.Sleep(100);

            //PlayStoneHit(0.0);
            //PlayBroomSound(0.0f);
            //PlayMoveSound(0.0);

            Thread.Sleep(2000);

            SoundEffect.MasterVolume = 1.0f;
        }

        public SoundManager()
        {
            MoveSound = moveSound.CreateInstance();
        }

        static SoundManager()
        {
            rnd = new Random();

            moveSound = SoundEffect.FromStream(Application.GetResourceStream(new Uri("/Curling;component/Sounds/Move.wav", UriKind.Relative)).Stream);   

            SoundEffect[] hitSound = new SoundEffect[5];
            HitSound = new SoundEffectInstance[4, 5];

            hitSound[0] = SoundEffect.FromStream(Application.GetResourceStream(new Uri("/Curling;component/Sounds/Hit/Hit100.wav", UriKind.Relative)).Stream);//TitleContainer.OpenStream("Sounds_/Hit/Hit100.wav"));
            hitSound[1] = SoundEffect.FromStream(Application.GetResourceStream(new Uri("/Curling;component/Sounds/Hit/Hit80.wav", UriKind.Relative)).Stream);//TitleContainer.OpenStream("Sounds_/Hit/Hit100.wav"));
            hitSound[2] = SoundEffect.FromStream(Application.GetResourceStream(new Uri("/Curling;component/Sounds/Hit/Hit60.wav", UriKind.Relative)).Stream);//TitleContainer.OpenStream("Sounds_/Hit/Hit100.wav"));
            hitSound[3] = SoundEffect.FromStream(Application.GetResourceStream(new Uri("/Curling;component/Sounds/Hit/Hit40.wav", UriKind.Relative)).Stream);//TitleContainer.OpenStream("Sounds_/Hit/Hit100.wav"));
            hitSound[4] = SoundEffect.FromStream(Application.GetResourceStream(new Uri("/Curling;component/Sounds/Hit/Hit20.wav", UriKind.Relative)).Stream);//TitleContainer.OpenStream("Sounds_/Hit/Hit100.wav"));

            for (int i = 0; i < 4; i++)
            {                
                HitSound[i, 0] = hitSound[0].CreateInstance();                
                HitSound[i, 1] = hitSound[1].CreateInstance();                
                HitSound[i, 2] = hitSound[2].CreateInstance();                
                HitSound[i, 3] = hitSound[3].CreateInstance();                
                HitSound[i, 4] = hitSound[4].CreateInstance();
            }

            SoundEffect broomSound = SoundEffect.FromStream(Application.GetResourceStream(new Uri("/Curling;component/Sounds/Broom.wav", UriKind.Relative)).Stream);
            BroomSound = broomSound.CreateInstance();
            BroomSound.IsLooped = true;

            //SoundEffect startMoveSound = SoundEffect.FromStream(Application.GetResourceStream(new Uri("/Curling;component/Sounds/StartMove.wav", UriKind.Relative)).Stream);
            //StartMoveSound = startMoveSound.CreateInstance();
            //FrameworkDispatcher.Update();
            //StartMoveSound.Volume = 0.0f;
            //StartMoveSound.Play();
            //Thread.Sleep(500);
            //StartMoveSound.Stop();
            //StartMoveSound.Volume = 1.0f;
            
           
            //MoveSound.IsLooped = true;

            //soundEffects = new SoundEffect[4];
            //soundEffectsInstances = new SoundEffectInstance[4];
            //StreamResourceInfo streamInfo = Application.GetResourceStream(
            //new Uri("/MyProjectName;component/Sound/Coyote.wav",
            //UriKind.Relative));
            //soundEffects[(int)Sounds.Hit] = SoundEffect.FromStream(TitleContainer.OpenStream("Sounds_/Hit.wav"));
            //soundEffectsInstances[(int)Sounds.Hit] = soundEffects[(int)Sounds.Hit].CreateInstance();

            //soundEffects[(int)Sounds.Broom] = SoundEffect.FromStream(TitleContainer.OpenStream("Sounds_/Broom.wav"));
            //soundEffectsInstances[(int)Sounds.Broom] = soundEffects[(int)Sounds.Broom].CreateInstance();

            //soundEffects[(int)Sounds.Move] = SoundEffect.FromStream(TitleContainer.OpenStream("Sounds_/Move.wav"));
            //soundEffectsInstances[(int)Sounds.Move] = soundEffects[(int)Sounds.Move].CreateInstance();
            //soundEffectsInstances[(int)Sounds.Move].IsLooped = true;

            //soundEffects[(int)Sounds.StartMove] = SoundEffect.FromStream(TitleContainer.OpenStream("Sounds_/StartMove.wav"));
            //soundEffectsInstances[(int)Sounds.StartMove] = soundEffects[(int)Sounds.StartMove].CreateInstance();
            //soundEffectsInstances[(int)Sounds.Hit].Play();
        }
    }
}
